home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Scanner / Scan.0.91 / Source / scanView.m < prev   
Text File  |  1996-02-03  |  7KB  |  281 lines

  1.  
  2. #import "scanView.h"
  3.  
  4. @implementation scanView
  5.  
  6. - initFrame:(const NXRect *)frameRect
  7. {
  8.     [super initFrame:frameRect];
  9.     [self setMyTrackingRect: YES];        // to enable mouse tracking
  10.     scalex = 1200.0/72.0;
  11.     scaley = 1200.0/72.0;
  12.     oldposition.x = -1.0;
  13.     
  14.     // size for 8.5 x 11 page, at 1200 dpi, scaled to 72 dpi.
  15.     [self setDrawSize:10200/scalex :14040/scaley];
  16.  
  17.     bitmapForView = 0x0;
  18.     [self clearDisplay:self];
  19.     [[self window] makeKeyAndOrderFront:self];
  20.     return self;
  21. }
  22.  
  23. - awakeFromNib
  24. {
  25.     [[self window] makeKeyAndOrderFront:self];
  26.     return self;
  27. }
  28.  
  29. - drawSelf:(const NXRect *)rects :(int)rectCount
  30. {
  31.     // max x-size = 8.5" x 1200 dpi = 10200 pixels.
  32.     // max y-size = 11.7" x 1200 dpi = 14040 pixels.
  33.     
  34.     if (clearFlag)
  35.     {
  36.        PSsetgray(NX_WHITE);
  37.        PSrectfill(bounds.origin.x, bounds.origin.y,
  38.                     bounds.size.width, bounds.size.height);
  39.     }
  40.  
  41.     if (bitmapForView && !clearFlag)
  42.     {    
  43.         [bitmapForView drawAt:&bitmapPos];
  44.     }
  45.     clearFlag = 0;
  46.     return self;
  47. }
  48.  
  49. - drawBitmap:(NXBitmapImageRep *)bitmap :(int)xstart :(int)ystart
  50. {
  51.     NXSize imageSize;
  52.     NXPoint start, finish;
  53.     
  54.     bitmapForView = bitmap;
  55.     bitmapPos.x = xstart;
  56.     bitmapPos.y = ystart;
  57.         
  58.     if (oldposition.x >= 0)
  59.     {
  60.         start.x = [startx intValue]/scalex;
  61.         start.y = (14040 - [starty intValue])/scaley;
  62.         finish.x = start.x + [width intValue]/scalex;
  63.         finish.y = start.y - [height intValue]/scaley;
  64.         [self doMyOwnUnhighlight:start :finish];
  65.     }
  66.     
  67.     [bitmapForView getSize:&imageSize];
  68.  
  69.     // correct pixel coordinates for origin.
  70.         
  71.     bitmapPos.x = bitmapPos.x/scalex;
  72.     bitmapPos.y = (14040 - bitmapPos.y)/scaley - imageSize.height;
  73.     
  74.     [self display];
  75.     return self;
  76. }
  77.  
  78. - clearDisplay:sender
  79. {
  80.     clearFlag = 1;
  81.     [self display];
  82.     return self;
  83. }
  84.  
  85. - setMyTrackingRect:(BOOL)flag
  86. {
  87.     NXRect visible;
  88.     
  89.     /* discard old tracking rect if present */
  90.     if (trackingRect) {
  91.         [window discardTrackingRect:trackingRect];
  92.         trackingRect = 0;
  93.     }
  94.  
  95.     if (flag) {
  96.         /* set new tracking rect if requested and if visible */
  97.         if ([self getVisibleRect:&visible]) {
  98.             [self convertRect:&visible toView:nil];
  99.             [window setTrackingRect:&visible
  100.                 inside:NO owner:self
  101.                 tag:1 left:NO right:NO];
  102.             trackingRect = 1;
  103.         }
  104.     }
  105.     return self;
  106. }
  107.  
  108. - mouseEntered:(NXEvent *)theEvent
  109. {
  110.     [window makeFirstResponder:self];
  111.     inside = YES;
  112.     return self;
  113. }
  114.     
  115. - mouseExited:(NXEvent *)theEvent
  116. {
  117.     inside = NO;
  118.     return self;
  119. }
  120.  
  121. - mouseDown:(NXEvent *)thisEvent
  122. /* modified from the online docs */
  123. {
  124.     int            shouldLoop = YES;
  125.     int            oldMask;
  126.     NXEvent       *nextEvent;
  127.     NXPoint           position;
  128.     NXPoint           newposition;
  129.     float           maxX = 10200/scalex;
  130.     float           maxY = 14040/scaley;
  131.  
  132.     if (oldposition.x >= 0)
  133.     {
  134.         position.x = [startx intValue]/scalex;
  135.         position.y = (14040 - [starty intValue])/scaley;
  136.         newposition.x = position.x + [width intValue]/scalex;
  137.         newposition.y = position.y - [height intValue]/scaley;
  138.         [self doMyOwnUnhighlight:newposition :position];
  139.     }
  140.     
  141.     position = thisEvent->location;
  142.     [self convertPoint:&position fromView:nil];
  143.  
  144.     if (position.x < 0) position.x = 0;
  145.     if (position.x > maxX) position.x = maxX;
  146.     if (position.y < 0) position.y = 0;
  147.     if (position.y > maxY) position.y = maxY;
  148.     
  149.     [startx setIntValue:position.x*scalex];
  150.     [starty setIntValue:14040 - position.y*scaley];
  151.     [width setIntValue:0];
  152.     [height setIntValue:0];
  153.     
  154.     oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
  155.  
  156.     while (shouldLoop) {
  157.         nextEvent = [NXApp getNextEvent:(NX_LMOUSEUPMASK |
  158.                                          NX_LMOUSEDRAGGEDMASK)];
  159.  
  160.         // get the position of the event in screen coordinates and
  161.         // convert to our particular view coordinates.
  162.         
  163.         newposition = nextEvent->location;
  164.         [self convertPoint:&newposition fromView:nil];
  165.  
  166.         if (newposition.x < 0) newposition.x = 0;
  167.         else if (newposition.x > maxX) newposition.x = maxX;
  168.         if (newposition.y < 0) newposition.y = 0;
  169.         else if (newposition.y > maxY) newposition.y = maxY;
  170.     
  171.         if (newposition.x < position.x)
  172.         {
  173.             [startx setIntValue:newposition.x*scalex];
  174.             [width setIntValue:(position.x - newposition.x)*scalex];
  175.         }
  176.         else
  177.         {
  178.             [startx setIntValue:position.x*scalex];
  179.             [width setIntValue:(newposition.x - position.x)*scalex];
  180.         }
  181.         
  182.         if (newposition.y > position.y)
  183.         {
  184.             [starty setIntValue:14040 - newposition.y*scaley];
  185.             [height setIntValue:(newposition.y - position.y)*scaley];
  186.         }
  187.         else
  188.         {
  189.             [starty setIntValue:14040 - position.y*scaley];
  190.             [height setIntValue:(position.y - newposition.y)*scaley];
  191.         }
  192.  
  193.         // We are interested in only 2 types of events.
  194.         
  195.         switch (nextEvent->type) {
  196.         case NX_LMOUSEUP:
  197.             shouldLoop = NO;
  198.             if (position.x != newposition.x) {
  199.                 [self doMyOwnHighlight:newposition :position];
  200.             }
  201.             // [self doMyOwnUnhighlight:newposition :position];
  202.             break;
  203.         case NX_LMOUSEDRAGGED:
  204.             [self doMyOwnHighlight:newposition :position];
  205.             break;
  206.         default:
  207.             break;
  208.         }
  209.  
  210.     }
  211.     [window setEventMask:oldMask];
  212.     return(self);
  213. }
  214.  
  215. - doMyOwnHighlight:(NXPoint)newposition :(NXPoint)position
  216. {    
  217.     BOOL    erase = YES;
  218.     
  219.     // if we are where we started from, do nothing.
  220.     
  221.     if (newposition.x == oldposition.x
  222.       && newposition.y == oldposition.y ) return self;
  223.     
  224.     if (oldposition.x < 0)                    // first time through,
  225.     {
  226.         erase = NO;                            // don't do an erase.
  227.         oldposition.x = newposition.x;        // last position = current pos.
  228.         oldposition.y = newposition.y;
  229.     }
  230.     
  231.     [self lockFocus];
  232.     
  233.     // erase the old highlight (if there is one)
  234.     
  235.     if (erase) PScompositerect(floor(position.x), floor(position.y),
  236.          floor(oldposition.x - position.x),
  237.         floor(oldposition.y - position.y), NX_HIGHLIGHT);
  238.  
  239.     // draw the new highlight
  240.     
  241.     PScompositerect(floor(position.x), floor(position.y),
  242.             floor(newposition.x - position.x),
  243.             floor(newposition.y - position.y), NX_HIGHLIGHT);
  244.  
  245.     [self unlockFocus];
  246.  
  247.     [window flushWindow];
  248.     oldposition.x = newposition.x;
  249.     oldposition.y = newposition.y;
  250.     return self;
  251. }
  252.  
  253. - doMyOwnUnhighlight:(NXPoint)newposition :(NXPoint)position
  254. {
  255.     [self lockFocus];
  256.  
  257.     // erase the old highlight (if there is one)
  258.     
  259.     PScompositerect(floor(position.x), floor(position.y),
  260.             floor(newposition.x - position.x),
  261.             floor(newposition.y - position.y), NX_HIGHLIGHT);
  262.  
  263.     [self unlockFocus];
  264.  
  265.     [window flushWindow];
  266.     oldposition.x = -1.0;            // so next time through, start fresh.
  267.     return self;
  268. }
  269.  
  270. - windowDidBecomeMain:sender
  271. {
  272.     return [self setMyTrackingRect: YES];
  273. }
  274.  
  275. - windowDidResignMain:sender
  276. {
  277.     return [self setMyTrackingRect: NO];
  278. }
  279.  
  280. @end
  281.